import type { App } from 'vue'
import { fxEventBus } from '@/js/eventBus'
import { fxEventBusKey } from '@/config/app_eventbus_config'
import type { FxItemQrCode } from '@/models/redCode'
const QRCODE_REG = /^([A-Za-z0-9]+)`~([0-9\.]+)`~([0-9\-]+)`~(\d+)`~(\d+)`~(\d+)`~(\d+)`~([0-9\.]+)`~(\d+)`~(\d+)`~(\d+)`~(\d+)`~(\d+)$/

class FxRedCode {
	public timeInterval = 0
	public redCode = ''
	public timer: number | undefined
	init () {
		document.querySelector('body')!.addEventListener('keydown', this.keyupHandler.bind(this))
	}

	keyupHandler (e: KeyboardEvent) {
		const key = e.key
		// if (/^F[0-9]{1}/.test(key)) {
		// 	key = e.key.replace(/^(F)([0-9]{1})/, '$2')
		// }
		if ((e.target instanceof Element && (e.target!.tagName === 'INPUT' || e.target!.tagName === 'TEXTAREA')) || key.length > 1) {
			return false
		}
		const interval = this.getTimeInterval()
		if (interval > 150) {
			this.redCode = ''
		}
		this.redCode += key
		window.clearTimeout(this.timer)
		this.timer = window.setTimeout(() => {
			if (!this.redCode) {
				return false
			}
			if (this.isQrCode(this.redCode)) {
				fxEventBus.emit(fxEventBusKey.RED_QR_CODE_EMIT, this.parseQrCode(this.redCode))
			} else {
				fxEventBus.emit(fxEventBusKey.RED_CODE_EMIT, this.redCode)
			}
		}, 300)
	}

	getTimeInterval () {
		const currentTime = new Date().getTime()
		const interval = !this.timeInterval ? 0 : currentTime - this.timeInterval
		this.timeInterval = currentTime
		return interval
	}

	addRedCodeListener (cb: Function) {
		fxEventBus.on(fxEventBusKey.RED_CODE_EMIT, cb)
	}

	removeRedCodeListener (cb: Function) {
		fxEventBus.off(fxEventBusKey.RED_CODE_EMIT, cb)
	}

	addRedQrCodeListener (cb: (arg: FxItemQrCode) => void) {
		fxEventBus.on(fxEventBusKey.RED_QR_CODE_EMIT, cb)
	}

	removeRedQrCodeListener (cb: Function) {
		fxEventBus.off(fxEventBusKey.RED_QR_CODE_EMIT, cb)
	}

	isQrCode (code: string) {
		return QRCODE_REG.test(code)
	}

	parseQrCode (code: string): Partial<FxItemQrCode> {
		const codeMatch = code.match(QRCODE_REG)
		if (!codeMatch) {
			return {}
		}
		return {
			entCode: codeMatch[1],
			version: codeMatch[2],
			itemCategory: codeMatch[3],
			itemCode: codeMatch[4],
			itemUnitId: codeMatch[5],
			itemBatchCode: codeMatch[6],
			serialNumber: codeMatch[7],
			itemAmount: codeMatch[8],
			suppilerCode: codeMatch[9],
			detailId: codeMatch[10],
			reserveField1: codeMatch[11],
			reserveField2: codeMatch[12],
			reserveField3: codeMatch[13]
		}
	}
}
export const fxRedCode = new FxRedCode()

const install = (app: App): void => {
	fxRedCode.init()
	app.config.globalProperties.$fxRedCode = fxRedCode
}

export default {
	install
}

